package com.vip.jwt.common.utils.sign;

import cn.hutool.core.codec.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;

public class AliyunSignUtil {

    /**
     * 获取请求签名
     * @param secret
     * @param params
     * @return
     * @throws Exception
     */
    public static String getSign(String secret, Map<String,String> params){
        // 4. 参数KEY排序
        TreeMap<String, String> sortParas = new TreeMap<String, String>(params);
        // 5. 构造待签名的字符串
        java.util.Iterator<String> it = sortParas.keySet().iterator();
        StringBuilder sortQueryStringTmp = new StringBuilder();
        while (it.hasNext()) {
            String key = it.next();
            sortQueryStringTmp.append("&").append(specialUrlEncode(key)).append("=").append(specialUrlEncode(params.get(key)));
        }
        String sortedQueryString = sortQueryStringTmp.substring(1);// 去除第一个多余的&符号
        String stringToSign = "GET" + "&" +
                specialUrlEncode("/") + "&" +
                specialUrlEncode(sortedQueryString);
        String sign = sign(secret + "&", stringToSign);
        // 6. 签名最后也要做特殊URL编码
        String signature = specialUrlEncode(sign);
        return signature + sortQueryStringTmp;
    }

    private static String specialUrlEncode(String value){
        try {
            return URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String sign(String accessSecret, String stringToSign){
        Mac mac = null;
        try {
            mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(accessSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
            byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
            return Base64.encode(signData);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

}
